467. 环绕字符串中唯一的子字符串
467. 环绕字符串中唯一的子字符串
Similar Question
leading to the advanced question
Solution Tips
方案一: 直接法
超时了
/**
* @param {string} s
* @return {number}
*/
var findSubstringInWraproundString = function(s) {
// 单字母子串肯定是全都有的
// 如果是多字母的子串, 就从头开始判断是否在连续的 字母表中, 如果是就 count++
const alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
// const abortLenList = {};
// let count = [...new Set(s.split(''))].length
// for (let i = 0; i < s.length; i++) {
// let start = s[i];
// let subLen = 1;
// let lastCharIndex = alphabet.indexOf(s[i]);
// // 单字母的, 需要判断一下子串是否相同, 去重后计数即可
// for (let j = i + 1; j < s.length; j++) {
// // 直接从多字母子串开始处理即可
// const newCharIndex = alphabet.indexOf(s[j])
// if (newCharIndex !== -1 && newCharIndex === (lastCharIndex + 1) % 26) {
// // 连续的子串, 且是字母表的子串
// subLen++
// // 再判断一下长度是否重复即可
// if (subLen > (abortLenList[start] || 0)) {
// count++;
// // 子串有可能重复出现, 要记录每个字母最长的 len, 下一次直接从这里开始就行
// abortLenList[start] = subLen
// }
// // 无论是否重复, 都要更新 last
// lastCharIndex = newCharIndex;
// }
// else {
// // 中断, 后面以 s[i] 开头的子串都不符合题意了
// break;
// }
// }
// }
// 参考上一题的思路, 不用每个子串遍历, 直接找到最长的子串, 然后那个子串就已经包含了所有的答案了
// 寻找最长子串
let longest = '';
for (let i = 0; i < s.length; i++) {
const start = s[i];
const alphabetIndex = alphabet.indexOf(start);
let nextChar = alphabet[(alphabetIndex+1) % 26]
for (let j = i + 1; j < s.length; j++) {
if (s[j] === nextChar) {
}
}
}
return count;
};
console.log(findSubstringInWraproundString('abaab'))
方案二: 动态规划
对于两个以同一个字符结尾的子串,长的那个子串必然包含短的那个
var findSubstringInWraproundString = function(p) {
const dp = new Array(26).fill(0);
let k = 0;
for (let i = 0; i < p.length; ++i) {
if (i > 0 && (p[i].charCodeAt() - p[i - 1].charCodeAt() + 26) % 26 === 1) { // 字符之差为 1 或 -25
++k;
} else {
k = 1;
}
dp[p[i].charCodeAt() - 'a'.charCodeAt()] = Math.max(dp[p[i].charCodeAt() - 'a'.charCodeAt()], k);
}
return _.sum(dp);
};